package com.jair.business.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jair.apicommon.model.InterfaceResponse;
import com.jair.apicommon.service.InterfaceInvokeService;
import com.jair.business.model.dto.Interface.InterfaceInfoAddRequest;
import com.jair.business.model.dto.Interface.InterfaceInfoInvokeRequest;
import com.jair.business.model.dto.Interface.InterfaceInfoQueryRequest;
import com.jair.business.model.dto.Interface.InterfaceInfoUpdateRequest;
import com.jair.business.model.entity.InterfaceInfo;
import com.jair.business.model.entity.User;
import com.jair.business.service.InterfaceInfoService;
import com.jair.business.service.UserService;
import com.jair.common.annotation.AuthCheck;
import com.jair.common.constant.bizz.ErrorCode;
import com.jair.common.constant.bizz.InterfaceInfoStatusEnum;
import com.jair.common.exception.BusinessException;
import com.jair.common.reponse.BaseResponse;
import com.jair.common.reponse.DeleteRequest;
import com.jair.common.reponse.IdRequest;
import com.jair.common.utils.ResultUtils;
import com.yupi.yuapiclientsdk.client.JairInterfaceClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 接口管理
 *
 */
@RestController
@RequestMapping("/interfaceInfo")
@Slf4j
public class InterfaceInfoController {

    @Resource
    private InterfaceInfoService interfaceInfoService;

    @Resource
    private UserService userService;

    // HTTP调用客户端（用于外部API调用）
    @Resource
    private JairInterfaceClient jairInterfaceClient;

    // Dubbo调用服务（用于内部服务调用）
    @DubboReference(version = "1.0.0", group = "dev", timeout = 5000, retries = 3)
    private InterfaceInvokeService interfaceInvokeService;

    // region 增删改查

    /**
     * 创建
     *
     * @param interfaceInfoAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Boolean> addInterfaceInfo(@RequestBody InterfaceInfoAddRequest interfaceInfoAddRequest, HttpServletRequest request) {
        Boolean result = interfaceInfoService.createInterface(interfaceInfoAddRequest, request);
        return ResultUtils.success(result);
    }

    /**
     * 删除
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteInterfaceInfo(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        Boolean result = interfaceInfoService.removeInterfaceById(deleteRequest,request);
        return ResultUtils.success(result);
    }

    /**
     * 更新
     *
     * @param interfaceInfoUpdateRequest
     * @param request
     * @return
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateInterfaceInfo(@RequestBody InterfaceInfoUpdateRequest interfaceInfoUpdateRequest,
                                                     HttpServletRequest request) {
        Boolean result = interfaceInfoService.updateInterfaceById(interfaceInfoUpdateRequest,request);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    public BaseResponse<InterfaceInfo> getInterfaceInfoById(Long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        InterfaceInfo interfaceInfo = interfaceInfoService.getById(id);
        return ResultUtils.success(interfaceInfo);
    }


    /**
     * 获取列表（仅管理员可使用）
     *
     * @param interfaceInfoQueryRequest
     * @return
     */
    @AuthCheck(mustRole = "admin")
    @GetMapping("/list")
    public BaseResponse<List<InterfaceInfo>> listInterfaceInfo(InterfaceInfoQueryRequest interfaceInfoQueryRequest) {
        List<InterfaceInfo> interfaceInfoList = interfaceInfoService.listInterface(interfaceInfoQueryRequest);
        return ResultUtils.success(interfaceInfoList);
    }

    /**
     * 分页获取列表（用户查看）
     *
     * @param interfaceInfoQueryRequest
     * @param request
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<InterfaceInfo>> listInterfaceInfoByPage(InterfaceInfoQueryRequest interfaceInfoQueryRequest, HttpServletRequest request) {
        Page<InterfaceInfo> interfaceInfoPage = interfaceInfoService.listInterfaceInfoByPage(interfaceInfoQueryRequest,request);
        return ResultUtils.success(interfaceInfoPage);
    }


    /**
     * 发布
     *
     * @param idRequest
     * @param request
     * @return
     */
    @PostMapping("/online")
    @AuthCheck(mustRole = "admin")
    public BaseResponse<Boolean> onlineInterfaceInfo(@RequestBody IdRequest idRequest,
                                                     HttpServletRequest request) {
        if (idRequest == null || idRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = idRequest.getId();
        // 判断是否存在
        InterfaceInfo oldInterfaceInfo = interfaceInfoService.getById(id);
        if (oldInterfaceInfo == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 判断该接口是否可以调用
        User loginUser = userService.getLoginUser(request);
        String accessKey = loginUser.getAccessKey();
        String secretKey = loginUser.getSecretKey();

        // 检查accessKey和secretKey是否为空
        if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(secretKey)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户accessKey或secretKey为空");
        }

        log.info("开始验证接口，accessKey: {}, secretKey: {}", accessKey, secretKey);

        try {
            com.yupi.yuapiclientsdk.model.User user = new com.yupi.yuapiclientsdk.model.User();
            user.setUsername("test");
            String username = jairInterfaceClient.getUserNameByPost(user);
            log.info("接口验证结果: {}", username);

            if (StringUtils.isBlank(username)) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "接口验证失败：返回结果为空");
            }
        } catch (Exception e) {
            log.error("接口验证异常: {}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "接口验证失败：" + e.getMessage());
        }
        // 仅本人或管理员可修改
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setId(id);
        interfaceInfo.setStatus(InterfaceInfoStatusEnum.ONLINE.getValue());
        boolean result = interfaceInfoService.updateById(interfaceInfo);
        return ResultUtils.success(result);
    }

    /**
     * 下线
     *
     * @param idRequest
     * @param request
     * @return
     */
    @PostMapping("/offline")
    @AuthCheck(mustRole = "admin")
    public BaseResponse<Boolean> offlineInterfaceInfo(@RequestBody IdRequest idRequest,
                                                      HttpServletRequest request) {
        if (idRequest == null || idRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = idRequest.getId();
        // 判断是否存在
        InterfaceInfo oldInterfaceInfo = interfaceInfoService.getById(id);
        if (oldInterfaceInfo == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 仅本人或管理员可修改
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setId(id);
        interfaceInfo.setStatus(InterfaceInfoStatusEnum.OFFLINE.getValue());
        boolean result = interfaceInfoService.updateById(interfaceInfo);
        return ResultUtils.success(result);
    }

    /**
     * 智能调用接口 - 混合架构
     */
    @PostMapping("/invoke")
    public BaseResponse<Object> invokeInterfaceInfo(@RequestBody InterfaceInfoInvokeRequest interfaceInfoInvokeRequest,
                                                    HttpServletRequest request) {
        if (interfaceInfoInvokeRequest == null || interfaceInfoInvokeRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = interfaceInfoInvokeRequest.getId();
        String userRequestParams = interfaceInfoInvokeRequest.getUserRequestParams();

        // 判断是否存在
        InterfaceInfo oldInterfaceInfo = interfaceInfoService.getById(id);
        if (oldInterfaceInfo == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        if (oldInterfaceInfo.getStatus() == InterfaceInfoStatusEnum.OFFLINE.getValue()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "接口已关闭");
        }

        User loginUser = userService.getLoginUser(request);

        // 智能选择调用方式
        String invokeMethod = determineInvokeMethod(request);
        log.info("选择调用方式: {}", invokeMethod);

        try {
            if ("dubbo".equals(invokeMethod)) {
                return invokeByDubbo(userRequestParams, oldInterfaceInfo, loginUser);
            } else {
                return invokeByHttp(userRequestParams, oldInterfaceInfo, loginUser);
            }
        } catch (Exception e) {
            log.error("调用失败，尝试降级", e);
            // 降级处理
            return invokeByHttp(userRequestParams, oldInterfaceInfo, loginUser);
        }
    }

    /**
     * 外部API调用 - 走HTTP + Gateway
     */
    @PostMapping("/external/invoke")
    public BaseResponse<Object> externalInvoke(@RequestBody InterfaceInfoInvokeRequest interfaceInfoInvokeRequest,
                                               HttpServletRequest request) {
        log.info("外部API调用 - 使用HTTP + Gateway");
        return invokeByHttp(interfaceInfoInvokeRequest.getUserRequestParams(),
                interfaceInfoService.getById(interfaceInfoInvokeRequest.getId()),
                userService.getLoginUser(request));
    }

    /**
     * 内部服务调用 - 走Dubbo
     */
    @PostMapping("/internal/invoke")
    public BaseResponse<Object> internalInvoke(@RequestBody InterfaceInfoInvokeRequest interfaceInfoInvokeRequest,
                                               HttpServletRequest request) {
        log.info("内部服务调用 - 使用Dubbo RPC");
        return invokeByDubbo(interfaceInfoInvokeRequest.getUserRequestParams(),
                interfaceInfoService.getById(interfaceInfoInvokeRequest.getId()),
                userService.getLoginUser(request));
    }

    /**
     * 判断调用方式
     */
    private String determineInvokeMethod(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        String referer = request.getHeader("Referer");
        String origin = request.getHeader("Origin");

        // 内部调用判断条件
        if (StringUtils.isNotBlank(userAgent) && userAgent.contains("Postman")) {
            return "dubbo"; // Postman测试用Dubbo
        }

        if (StringUtils.isNotBlank(referer) && referer.contains("localhost:8080")) {
            return "dubbo"; // 同域调用用Dubbo
        }

        if (StringUtils.isNotBlank(origin) && origin.contains("localhost:8080")) {
            return "dubbo"; // 同域调用用Dubbo
        }

        // 默认使用HTTP（外部调用）
        return "http";
    }

    /**
     * Dubbo调用方式
     */
    private BaseResponse<Object> invokeByDubbo(String userRequestParams, InterfaceInfo interfaceInfo, User loginUser) {
        long startTime = System.currentTimeMillis();

        try {
            InterfaceResponse response = interfaceInvokeService.invokeInterfaceWithAuth(
                    userRequestParams,
                    interfaceInfo.getMethod(),
                    userRequestParams,
                    loginUser.getAccessKey(),
                    loginUser.getSecretKey()
            );

            long duration = System.currentTimeMillis() - startTime;
            log.info("Dubbo调用完成 - 耗时: {}ms, 结果: {}", duration, response.getResult());

            if (response.getCode() == 200) {
                return ResultUtils.success(response.getResult());
            } else {
                return ResultUtils.error(ErrorCode.SYSTEM_ERROR, response.getMessage());
            }
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("Dubbo调用失败 - 耗时: {}ms, 错误: {}", duration, e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "Dubbo调用失败: " + e.getMessage());
        }
    }

    /**
     * HTTP调用方式
     */
    private BaseResponse<Object> invokeByHttp(String userRequestParams, InterfaceInfo interfaceInfo, User loginUser) {
        long startTime = System.currentTimeMillis();

        try {
            com.yupi.yuapiclientsdk.model.User user = new com.yupi.yuapiclientsdk.model.User();
            user.setUsername(userRequestParams);
            String result = jairInterfaceClient.getUserNameByPost(user);

            long duration = System.currentTimeMillis() - startTime;
            log.info("HTTP调用完成 - 耗时: {}ms, 结果: {}", duration, result);

            return ResultUtils.success(result);
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("HTTP调用失败 - 耗时: {}ms, 错误: {}", duration, e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "HTTP调用失败: " + e.getMessage());
        }
    }

}
